# --------------------------------------------------------------------------------------------------------------------
# Project:             Digital Payment System (DPS)
# Website:             http://code.google.com/p/dps-x509/
# Purpose of document: This class hold all of the attributes (we care about) for our certificates
# --------------------------------------------------------------------------------------------------------------------
import sys, string, logging

sys.path.append("..")
  
try:
  import keyczar.keys as keys
except ImportError:
  from keyczar import *
  

import dps.errors
import dps.utils
import dps.x509AttributeAndValue

# --------------------------------------------------------------------------------------------------------------------
class CertificateType:
  ISSUER_CERTIFICATE      = 0
  TOKEN_CERTIFICATE       = 1
  TOKEN_CHAIN_CERTIFICATE = 2

# --------------------------------------------------------------------------------------------------------------------
class X509CertificateParams:
  """ Class holds properties of x509 certificate 
      Not all properties are exposed only the ones of interest to us """ 

# --------------------------------------------------------------------------------------------------------------------
  def __init__(self):
    """ constructor """
    self.__subject_     = None
    self.__issuer_      = None
    self.redeemer_      = ""
    self.exchanger_     = ""
    self.tokenType_     = ""
    self.tokenQuantity_ = -1.0
    self.registrar_     = ""
    self.__publicKey_   = None
    self.isCA_          = False
    self.id_            = ""
    self.posInChain_    = 0
    
# --------------------------------------------------------------------------------------------------------------------
  def getPublicKey(self):
    """ 
    getter
    @rtype: keyczar.keys.RsaPublicKey
    """
    return self.__publicKey_

# --------------------------------------------------------------------------------------------------------------------
  def setPublicKey(self, publicKey):
    """ 
    setter
    @param publicKey: keyczar.keys.RsaPublicKey or None 
    """
    dps.utils.assertion(not publicKey or isinstance(publicKey, keys.RsaPublicKey), \
                        "X509CertificateParams.setPubKey: pubkey type mismatch")
    self.__publicKey_ = publicKey
    
# --------------------------------------------------------------------------------------------------------------------
  def getIssuer(self):
    """ 
    getter 
    @rtype: dps.x509AttribueAndValue.X509AttribueAndValueList
    """
    return self.__issuer_

# --------------------------------------------------------------------------------------------------------------------
  def setIssuer(self, issuer):
    """ setter
    @param issuer: issuer rdn
    @type  issuer: dps.x509AttribueAndValue.X509AttribueAndValueList
    """
    dps.utils.assertion(not issuer or isinstance(issuer, dps.x509AttributeAndValue.X509AttributeAndValueList), \
                        "X509CertificateParams.setIssuer: issuer type mismatch")
    self.__issuer_ = issuer  
  
# --------------------------------------------------------------------------------------------------------------------
  def getSubject(self):
    """ 
    getter 
    @rtype: dps.x509AttribueAndValue.X509AttribueAndValueList
    """
    return self.__subject_

# --------------------------------------------------------------------------------------------------------------------
  def setSubject(self, subject):
    """ 
    getter 
    @rtype: dps.x509AttribueAndValue.X509AttribueAndValueList
    """
    dps.utils.assertion(not subject or isinstance(subject, dps.x509AttributeAndValue.X509AttributeAndValueList), \
                        "X509CertificateParams.setSubject: subject type mismatch")
    self.__subject_ = subject

# --------------------------------------------------------------------------------------------------------------------
  def hasCompleteTokenData(self):
    """ 
    is there enough data in the parameters for it to be considered a token 
    @rtype: bool
    @deprecated: should now use isTokenCertificate
    """
    isComplete = not self.redeemer_ == "" and not self.tokenType_ == "" and self.tokenQuantity_ > 0 and \
           not self.registrar_ == "" and self.__publicKey_ and not self.__subject_ == None and \
           not self.__issuer_ == None
    dps.utils.out("X509CertificateParams.hasCompleteTokenData: %s" % isComplete)
    return isComplete

# --------------------------------------------------------------------------------------------------------------------
  def certificateType(self):
    """
    checks if it is a token certificate, then a token chain certificate otherwise it is assumed to be an issuer ceritificate
    @rtype:  int
    @return: CertificateType.ISSUER_CERTIFICATE, CertificateType.TOKEN_CERTIFICATE or CertificateType.TOKEN_CHAIN_CERTIFICATE
    """
    ret = CertificateType.ISSUER_CERTIFICATE
    if not self.redeemer_ == "" and not self.tokenType_ == "" and self.tokenQuantity_ > 0 and \
           not self.registrar_ == "" and self.__publicKey_ and not self.__subject_ == None and \
           not self.__issuer_ == None:
      ret = CertificateType.TOKEN_CERTIFICATE
    elif not self.id_ == "" and not self.posInChain_ > 0 and not self.__subject_ == None and \
         not self.__issuer_ == None:
      ret = CertificateType.TOKEN_CHAIN_CERTIFICATE
    return ret
    
# --------------------------------------------------------------------------------------------------------------------
  def isIssuerCertificate(self):
    ret = self.certificateType()
    return ret == CertificateType.ISSUER_CERTIFICATE
    
# --------------------------------------------------------------------------------------------------------------------
  def isTokenCertificate(self):
    ret = self.certificateType()
    return ret == CertificateType.TOKEN_CERTIFICATE

# --------------------------------------------------------------------------------------------------------------------
  def isTokenChainCertificate(self):
    ret = self.certificateType()
    return ret == CertificateType.TOKEN_CHAIN_CERTIFICATE    
    
# --------------------------------------------------------------------------------------------------------------------
  def __str__(self):
    """ str operator """
    val = "subject: "+str(self.__subject_)+\
    " issuer: "+str(self.__issuer_)+\
    " redeemer: "+self.redeemer_+\
    " tokenType: "+self.tokenType_+\
    " tokenQuantity: "+str(self.tokenQuantity_)+\
    " registrar: "+self.registrar_+\
    " publicKey: "+dps.utils.stringify(self.__publicKey_)+\
    " isCA: "+str(self.isCA_)+\
    " exchanger: "+self.exchanger_+\
    " id: "+str(self.id_)+\
    " PosInChain: "+str(self.posInChain_)
    return val